# 构建用户画像
import io
import csv
import json
import sys
import time

import jieba
import requests
from neo4j import graph

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.metrics.pairwise import cosine_similarity
from py2neo import Graph


sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

rcsv = open('data/data2.csv', 'r', encoding="utf-8")
reader = csv.reader(rcsv)
data = list(reader)
graph = Graph("http://localhost/:7474", auth=("neo4j", "Xiyou666"), name="neo4j")
# 修改成自己的api key和secret key
API_KEY = "8QRGwlx3EiTgFhx8isqSxGye"
SECRET_KEY = "u3Nu9cZRfjrxKWCjikhlKW0LM35TOPYM"

class UserProfile:
    def __init__(self, skills, job):
        self.skills = skills
        self.job = job


def get_access_token():
    """
    使用 AK，SK 生成鉴权签名（Access Token）
    :return: access_token，或是None(如果错误)
    """
    url = "https://aip.baidubce.com/oauth/2.0/token"
    params = {"grant_type": "client_credentials", "client_id": API_KEY, "client_secret": SECRET_KEY}
    return str(requests.post(url, params=params).json().get("access_token"))



def getinfos(user_profile):
    url = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/eb-instant?access_token=" + get_access_token()
    # 注意message必须是奇数条
    payload = json.dumps({
        "messages": [
            {
                "role": "user",
                "content": "这是用户的技能" + user_profile.skills + "他的期望工作是" + user_profile.job + "请给他一些提升的意见"
            }
            # ,
            # {
            #    "role": "assistant",
            #    "content": "你好，有什么我可以帮助你的吗？"
            # }
        ]
    })
    headers = {
        'Content-Type': 'application/json'
    }

    response = requests.request("POST", url, headers=headers, data=payload)

  #  print(response.text)
    # 将JSON字符串解析为字典
    data = json.loads(response.text)


  #  print(response.text)#返回的是jason格式 就是{} 里面也是{}
    # 将JSON字符串解析为字典
    data = json.loads(response.text)
    #注意是jsob字符串
    return  data
    # 将JSON字符串解析为字典
    #data = json.loads(response.text)

    # 提取result键的值
   # result = data['result']
    #print("我们给用户的提升建议如下"+result)
   # json_object = json.loads(result)
  #  print(json_object)
kk={}
def job_similarity(text2):
    for i in range(1, len(data)):
        query2 = """
                    Match (n:Skills_job) 
                    return properties(n) AS properties,ID(n) as id, labels(n) AS label
                  """
        # 查找到了就可以找对应节点的属性了
        result2 = graph.run(query2).data()
        # print(result2[0]['properties']['id'])
        a = result2[i - 1]['properties']['job']
        # 上面的for主要是为了遍历skills_job标签的节点 方便匹配用户的职业  前提是节点已经存在
        # 然后就是计算相似度  返回对应的技能
        #   for city in job_city:

        seg_list1 = jieba.cut(a, cut_all=False)  # 精确模式分词
        # print(" ".join(seg_list))
        str1 = ",".join(seg_list1)  # List转字符串

        seg_list1 = jieba.cut(text2, cut_all=False)  # 精确模式分词
        # print(" ".join(seg_list))
        str2 = ",".join(seg_list1)  # List转字符串
        vectorizer = CountVectorizer().fit_transform([str1, str2])
        vectors = vectorizer.toarray()
        # print(vectors)
        # 计算余弦相似度
        cosine_sim = cosine_similarity(vectors)
        # print("Cosine Similarity:", cosine_sim[0][1])
        kk[a] = cosine_sim[0][1]
    # print(kk)
    # 结果是全部为0


#传入的参数是用户的信息 后端的Userprofile
def ability_prase(user_profile):
    expected_skills = user_profile.skills
    skills_list = expected_skills.split(',')# 返回的是列表 也就是list() 函数的返回值 里面的内容是字符串
    #用,分隔开 每个就是一个单独的字符串了
    skills = [s.strip() for s in skills_list]
    """
    当使用 skills = [s.strip() for s in skills_list] 这行代码时，它会创建一个新的列表 skills，
    其中包含了对 skills_list 中每个元素进行去除首尾空格操作后的结果。
    这行代码使用了列表推导式（list comprehension），它可以简洁地对列表中的元素进行处理，并生成一个新的列表。
    先遍历skills_list 再对遍历到的s进行s.strip处理
    """
    user_skills = ','.join(skills) #变成字符串
    """
    格式展示 是一个key-value的格式
    skills=['hello','good','boy','doiido']
user_skills = {"skills": ','.join(skills)}
print(user_skills)
{'skills': 'hello,good,boy,doiido'}
    """
    #然后就获得了用户的所有技能

    #需要知道name节点 就是用户的职业
    expected_job = user_profile.job
    #第二步就是和期望职位进行匹配  遍历neo4j中的节点
    job_similarity(expected_job)

    list = []  # 定义一个列表 放字典的value值

    a1 = sorted(kk.items(), key=lambda x: x[1], reverse=True)  # 这个是对kk字典 根据value进行降序排列 升序的话 只需要去掉后面的reverse就可以了
    #print(a1)
    # 这是结果 [('计算机视觉工程师', 0.8660254037844388), ('算法工程师', 0.7071067811865475),
    #print(a1[0])
    # 这是结果('计算机视觉工程师', 0.8660254037844388)   ()代表是元组
    #print(a1[0][1])
    # 结果 0.8660254037844388
    #print(a1[0][0])
    job = a1[0][0]
    # 这是工作的名字 就是用户匹配的工作


  #得到了对应的工作就返回对应的技能 就是对Skills_job标签的节点 根据job查name
    for i in range(1, len(data)):
        """
        query2 =
               MATCH (skills:Skills_job {job: $job})
              RETURN skills      
              result = graph.run(query2, job=a1[0][0]).data()
              如果是用这种查询语句 得到的结果就是这样
              #得到的结果
# [{'skills': Node('Skills_job', job='计算机视觉工程师', name='熟悉各类相机成像特点和光源光路设计原理,能熟练使用Halcon、OpenCV任一种视觉软件库解决边缘提取、检测、定位等问题,精通C#、C/C++编程语言')}]
#我们需要取出其中的技能 也就是name
不方便取出数据              
        """
        query2 = """
          Match(n: Skills_job {job: $job})
        return properties(n)
        AS
        properties, ID(n) as id, labels(n)
        AS
        label
        """
        result = graph.run(query2, job=a1[0][0]).data()
    #print(result)
   # print(result[0]['properties']['name'])#这就获取了对应的技能 是以String类型出现的
    #熟悉各类相机成像特点和光源光路设计原理,能熟练使用Halcon、OpenCV任一种视觉软件库解决边缘提取、检测、定位等问题,精通C#、C/C++编程语言 比如这就是输出的结果
    #现在进行测试 这就是简历分析过后的

    #适配度匹配
    d=result[0]['properties']['name']
    seg_list1 = jieba.cut(d, cut_all=False)  # 精确模式分词
    #print(" ".join(seg_list))
    str1 = ",".join(seg_list1)#List转字符串
    #print(str1)
    #print("------------------------------------------------------------------")
    seg_list2 = jieba.cut(user_skills, cut_all=False)  # 精确模式分词 这里有个注意的点 开头不能有(等字符 因为我之前的格式是(1  但是 用户上传过来的似乎都是字符串 不会有这个 那不管
    #print(" ".join(seg_list))
    str2=",".join(seg_list2)
    #print(str2)

    vectorizer = CountVectorizer().fit_transform([str1, str2])
    vectors = vectorizer.toarray()
    #print(vectors)
    # 计算余弦相似度
    cosine_sim = cosine_similarity(vectors)
    results=[]
  #  print("岗位契合度:", cosine_sim[0][1])
    str ={'岗位契合度':cosine_sim[0][1]}#注意字典必须是
    #dict类型
    #json_object = json.dumps(str)
    # 上面就是根据技能的余弦相似度得到的契合度 不过要修改一下技能对应才行
    user1 = UserProfile(user_skills, user_profile.job)
    jason = getinfos(user1)
    #这个是dict 我之前一直以为是json格式 结果接口返回来的是dict  只用转换为str
   # jason.update(str)
    #这个是str类型
    results.append(str)
    results.append(jason)
    json_str = json.dumps(results, ensure_ascii=False)
    #json_str 为str类型  这个dumps方法好像是把dict转换为json 但是这里显示的是str
    return  json_str

if __name__ == '__main__':
    arguments = ''
    # 打印传递的参数
    if len(sys.argv) > 1:
        for arg in sys.argv[1:]:
            arguments = ' '.join(sys.argv[1:])
    # print(arguments)
    # 分割字符串，从后面开始
    fields = arguments.split(',')
    # 提取字段
    job = fields[-1]
    skills = ','.join(fields[0])
    user_profile = UserProfile(skills, job)
    jason = ability_prase(user_profile)
    print(jason)
   # print(jason) #返回的是str  这就是为什么不能直接通过['result']取出来的原因  我觉得我应该直接通过转换为dict 然后取出对应元素 然后放在一起 再转换为str返回去就行
   # print(type(jason)) #返回的是str 然后是根据jobRec那样的方法定制数据 数据的大概在notebook里面 可以自己去看  然后就可以再通过前端处理了 因为他会把String转换为jasonArray

